#include "StruggleLayer.h"

#define DRAG_SPRITE_OPACITY 50

StruggleLayer::StruggleLayer(){
	m_dragSlotKey = EMPTY_STRING;
	m_attachedSprites = new map<string,PeaShooter*>();
	m_attachedBulletBalls = new map<string,BulletBall*>();
	m_zombies = new map<unsigned int,Zombie*>(); 
	MapGrid* mapGrid = MapGrid::GetSharedCache();
	m_graveFactory = GraveFactory::Create(MapGrid::GetRightOutRange(),MapGrid::GetLeftOutRange());
}

StruggleLayer::~StruggleLayer(){
	delete m_attachedBulletBalls;
	delete m_attachedSprites;
	delete m_zombies;

	MapGrid::ClearSharedCache();
	GraveFactory::Destory();
}

bool StruggleLayer::init(){

	bool bRet = false;

	do 
	{
		CC_BREAK_IF(! CCLayer::init());
		m_state = kSpriteBrickUngrabbed;
		m_dragSprite = PeaShooter::create();
		m_dragSprite->setAnchorPoint(RectLayout::TopLeft());
		m_dragSprite->setVisible(false);
		this->addChild(m_dragSprite);

		bRet = true;

		this->schedule(schedule_selector(StruggleLayer::DoStruggle));

	} while (0);

	return bRet;
}

void StruggleLayer::onEnter()
{
	CCNode* pSceneLayer = this->getParent()->getChildByTag(kSceneLayer);
	SpriteBrick* psb = (SpriteBrick*)pSceneLayer->getChildByTag(kPeaShooterSpriteBrick);
	psb->AddTouchEventBeginHandle(this);
	psb->AddTouchEventMoveHandle(this);
	psb->AddTouchEventCompleteHandle(this);	

	CCLayer::onEnter();
}

void StruggleLayer::touchBeginHandler( CCEvent* e)
{
	if(!GameSetting::isGameStart) return;
	if(m_state != kSpriteBrickUngrabbed) return;
	m_state = kSpriteBrickGrabbed;		
	
	CCNode* pSceneLayer = this->getParent()->getChildByTag(kSceneLayer);
	SpriteBrick* psb = (SpriteBrick*)pSceneLayer->getChildByTag(kPeaShooterSpriteBrick);	

	CCPoint cp = psb->getPosition();
	MapGrid* mapGrid = MapGrid::GetSharedCache();
	MapSlot* slot = mapGrid->SlotOverlapped(&cp);

	if(slot)
	{
		m_dragSprite->setOpacity(DRAG_SPRITE_OPACITY);
		m_dragSprite->setVisible(true);
		m_dragSprite->setPosition(mapGrid->GetSlotCoordinate(slot));
	}else{
		m_dragSprite->setVisible(false);
	}
}

void StruggleLayer::touchMoveHandler( CCPoint touchPoint, CCEvent* e)
{
	if(m_state == kSpriteBrickGrabbed){
		CCNode* pSceneLayer = this->getParent()->getChildByTag(kSceneLayer);
		SpriteBrick* psb = (SpriteBrick*)pSceneLayer->getChildByTag(kPeaShooterSpriteBrick);

		MapGrid* mapGrid = MapGrid::GetSharedCache();
		MapSlot* slot = mapGrid->SlotOverlapped(&touchPoint);
		if(slot)
		{
			m_dragSprite->setVisible(true);
			m_dragSprite->setAnchorPoint(RectLayout::Center());
			m_dragSprite->setPosition(mapGrid->GetSlotCoordinate(slot));
			m_dragSlotKey = slot->GetKey();
		}else{
			m_dragSprite->setVisible(false);
			m_dragSlotKey = EMPTY_STRING;
		}
	}
}

void StruggleLayer::touchCompleteHandler(CCEvent* e)
{
	if(m_state != kSpriteBrickGrabbed) return;
	MapGrid* mapGrid = MapGrid::GetSharedCache();
	if(m_dragSlotKey != EMPTY_STRING){
		MapSlot* slot = mapGrid->GetSlotByKey(m_dragSlotKey);
		if(slot)
		{
			map<string,PeaShooter*>::iterator it = m_attachedSprites->find(slot->GetKey());

			if(it == m_attachedSprites->end()){
				CreatePeaShooterAndBullet(mapGrid, slot);
			}
		}
	}
	
	m_state = kSpriteBrickUngrabbed;
	m_dragSprite->setAnchorPoint(RectLayout::TopLeft());
	m_dragSprite->setVisible(false);
}

void StruggleLayer::CreatePeaShooterAndBullet( MapGrid* mapGrid, MapSlot* slot ) 
{
	PeaShooter* newSprite = PeaShooter::create();
	newSprite->setAnchorPoint(RectLayout::Center());
	newSprite->setVisible(true);
	this->addChild(newSprite);
	newSprite->setPosition(mapGrid->Set2Slot(slot));
	(*m_attachedSprites)[slot->GetKey()] = newSprite;

	BulletBall* newBulletBall = BulletBall::create(mapGrid->GetSlotCoordinate(slot),mapGrid->GetOutRangeCoordinate(slot));
	this->addChild(newBulletBall);
	(*m_attachedBulletBalls)[slot->GetKey()] = newBulletBall;
}

void StruggleLayer::DoStruggle( float dt ){
	if(GameSetting::isGameStart){
		Zombie* newZombie =  m_graveFactory->CreateZombie();
		if(newZombie!=NULL){
			map<unsigned int,Zombie*>::iterator it = m_zombies->find(newZombie->Key());
			if(it == m_zombies->end()){
				(*m_zombies)[newZombie->Key()] = newZombie;
				this->addChild(newZombie);
			}
		}

		for(map<string,BulletBall*>::iterator bbit = m_attachedBulletBalls->begin();bbit!= m_attachedBulletBalls->end();bbit++){
			if(MapGrid::GetSharedCache()->IsOutOfRange(bbit->second->GetLocation())){
				bbit->second->ReStartMove();
			}else{
				for(map<unsigned int,Zombie*>::iterator zbit = m_zombies->begin();zbit!= m_zombies->end();zbit++){
					if(zbit->second->IsLive() && bbit->second->Rect().intersectsRect(zbit->second->Rect())){
						bbit->second->ReStartMove();
						zbit->second->SetInValid();
					}else{
						if(MapGrid::GetSharedCache()->IsOutOfRange(zbit->second->GetLocation())){
							zbit->second->SetInValid();
						}
					}
				}
			}
		}
	}
}